package ;
import haxe.xml.Fast;
import haxe.xml.Parser;
import openfl.Assets;
import flixel.FlxCamera;
import flixel.FlxG;
import flixel.util.FlxPoint;
/**
 * ...
 * @author Federico Donnet
 */
class Utils
{

	//--------------------------------------------------------------------------------//
	//---*Atributos:
	//--------------------------------------------------------------------------------//	
	
	
	//--------------------------------------------------------------------------------//
	//---*Source del XML que estructura los Levels:
	//--------------------------------------------------------------------------------//
	public inline static var LEVELMANAGERTMX:String					=	"assets/data/Levels/LevelManagerXML.xml";
	
	
	//--------------------------------------------------------------------------------//
	//---*Nombre de los layers de interes:
	//--------------------------------------------------------------------------------//
	public inline static var SOLID_LAYER:String						=	"SolidLayer"; 
	public inline static var ITEM_LAYER:String						=	"ItemLayer"; 
	
	
	//--------------------------------------------------------------------------------//
	//---*Source de los tilesets que se usarian:
	//--------------------------------------------------------------------------------//
	public inline static var TILESET_01:String						=	"assets/images/tileset01.png";
	
	
	
	//--------------------------------------------------------------------------------//
	//---*Nombres de los Levels:
	//--------------------------------------------------------------------------------//
	public inline static var LEVEL_01_NAME:String					=	"Level01";
	public inline static var LEVEL_02_NAME:String					=	"Level02"; 
	public inline static var LEVEL_03_NAME:String					=	"Level03"; 
	public inline static var LEVEL_04_NAME:String					=	"Level04"; 
	public inline static var LEVEL_05_NAME:String					=	"Level05"; 
	
	
	
	//---*Lee el TMX ingresado en el 1er parametro y busca el nodo con el nombre indicado en el 2do parametro:
	public	static	function	ReadXML(xmlSource:String, levelName:String):Array<String>  
	{					
		//---*Array para almacenar los nodos "Patron":
		var	patronSourceList:Array<String>   		=	new Array<String>();
		var	xml:Xml									=	null;
		var fastXml:Fast							=	null;
		//---*Obtiene el archivo .xml y lo parsea:
		xml 										=	Parser.parse(Assets.getText(xmlSource));
		//---*Define al objeto Fast para que podamos tener una lectura en base a Elementos (nodos), atributos (valores, datos) , etc:
		fastXml 									=	new Fast(xml);
		//---*Crea un objeto Fast auxiliar:
		var GameLevels:Fast 						=	null;
		
		//---*Ve si tiene el Elemento Root o Nodo Inicial llamado "Subjects":
		if (!fastXml.hasNode.GameLevels)
			return null;		
		//---*Almacena el root:
		GameLevels 									=	fastXml.node.GameLevels;
		//---*Ve si el Root pose nodos "Level":
		if (!GameLevels.hasNode.GameLevel)
			return null;
				
		//---*Recorre todos los level's desde el root "Levels":
		for ( level in GameLevels.nodes.GameLevel ) 
		{			
			
			//---*Si el atributo "index" del Nodo Level corresponde al buscado:
			if (level.has.name && level.att.name 	== levelName)
			{
				//---*Encontramos el level buscado, vemos si posee el nodo "Patrons":
				if (level.hasNode.Patrons)
				{
					//---*Almacenamos el Nodo "Patrons":
					var patrons = level.node.Patrons;
					
					//---*Recorremos el nodo "Patrons" en busca de los childs "Patron":
					for ( patron in patrons.nodes.Patron ) 
					{
						//---*Almacenamos el atributo "source" de cada patron en la lista:						
						patronSourceList.push(patron.att.source);						
					}
				}
			}			
		}
		
		//---*Aviso de error:
		if (patronSourceList.length == 0)
		{
			trace("No se encuentra el level buscado");
		}
		
		return	patronSourceList;
		
		
	}
	
	public	static	function	GetConectionsData(xmlSource:String, levelName:String, source:String):Dynamic 
	{
		var conectionsData:Dynamic					=	null;
		var	xml:Xml									=	null;
		var fastXml:Fast							=	null;
		//---*Obtiene el archivo .xml y lo parsea:
		xml 										=	Parser.parse(Assets.getText(xmlSource));
		//---*Define al objeto Fast para que podamos tener una lectura en base a Elementos (nodos), atributos (valores, datos) , etc:
		fastXml 									=	new Fast(xml);
		//---*Crea un objeto Fast auxiliar:
		var GameLevels:Fast 						=	null;
		
		//---*Ve si tiene el Elemento Root o Nodo Inicial llamado "Subjects":
		if (!fastXml.hasNode.GameLevels)
			return null;		
		//---*Almacena el root:
		GameLevels 									=	fastXml.node.GameLevels;
		//---*Ve si el Root pose nodos "Level":
		if (!GameLevels.hasNode.GameLevel)
			return null;
				
		//---*Recorre todos los level's desde el root "Levels":
		for ( level in GameLevels.nodes.GameLevel ) 
		{			
			
			//---*Si el atributo "index" del Nodo Level corresponde al buscado:
			if (level.has.name && level.att.name 	== levelName)
			{
				//---*Encontramos el level buscado, vemos si posee el nodo "Patrons":
				if (level.hasNode.Patrons)
				{
					//---*Almacenamos el Nodo "Patrons":
					var patrons = level.node.Patrons;
					
					//---*Recorremos el nodo "Patrons" en busca de los childs "Patron":
					for ( patron in patrons.nodes.Patron ) 
					{
						//---*Ve que se trate del patron ingresado! (lo verifica por el source):
						if (patron.has.source && patron.att.source == source)
						{
							if (patron.hasNode.Conections)
							{
								//---*Almacenamos el Nodo "Conections":
								var conections = patron.node.Conections;
								if (conections.hasNode.Conection)
								{
									var conection = conections.node.Conection;
									conectionsData = conection.innerData;									
								}								
							}
						}												
					}
				}
			}			
		}
		
		if (conectionsData == null)
		{
			trace("El Patron no posee conexiones");
		}
		
		return conectionsData;
	}
	
	//--------------------------------------------------------------------------------//
	//---*Funcion auxiliar para leer una layer y retornar los datos de la mismas:
	//--------------------------------------------------------------------------------//
	public	static	function 	loadTilemap(tileGraphic :Dynamic, layerName :String, mapElement:Fast):Dynamic
	{				
		for ( layer in mapElement.nodes.layer ) 
		{			
			if (layer.has.name && layer.att.name == layerName)
			{
				var layerData 		=	layer.node.data.innerData;
				//---*Retorna el csv:				
				return layerData;
			}
		}
		throw "ERROR: Couldn't find tilemap layer: " + layerName;		
	}
	
	
	/*
	* 
	* @param	A function that takes in the following parameters (name:String, data:Xml):Void (returns Void) that spawns entities based on their name.
	* @param	The name of the layer the entities are stored in Ogmo editor. Usually "entities" or "actors"
	*/ 
	/*
	public static	function loadObjects(objectLoadCallback: Fast -> Void, ObjectLayer:String, mapElement:Fast):Void
	{		
		
		for ( objectgroup in mapElement.nodes.objectgroup ) 
		{
			if (objectgroup.has.name && objectgroup.att.name == ObjectLayer)
			{
				for ( obj in objectgroup.nodes.object )
				{
					//---*Retorna el Objeto:
					objectLoadCallback(obj);
				}
				return;		
			}
		}
	}
	*/
	/*
	* 
	* @param	A function that takes in the following parameters (name:String, data:Xml):Void (returns Void) that spawns entities based on their name.
	* @param	The name of the layer the entities are stored in Ogmo editor. Usually "entities" or "actors"
	*/ 
	public static	function loadObjects(ObjectLayer:String, mapElement:Fast, type:String):Array<Fast>
	{		
		var objectList:Array<Fast> = new Array<Fast>();
		for ( objectgroup in mapElement.nodes.objectgroup ) 
		{
			if (objectgroup.has.name && objectgroup.att.name == ObjectLayer)
			{
				for ( obj in objectgroup.nodes.object )
				{
					//---*Si el type es el buscado:
					if (obj.has.type && obj.att.type == type)
					{
						//---*Aniade el Objeto:
						objectList.push(obj);
					}
				}
				
			}
		}
		return objectList;		
	}
	
	public static function OnScreen(point:FlxPoint,width:Float,height:Float, Camera:FlxCamera,offsetX:Float,offsetY:Float):Bool
	{		
		return (point.x + width > 0) && (point.x < Camera.width + offsetX) && (point.y + height > 0) && (point.y < Camera.height + offsetY);
	}
}